﻿using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using CashOrCard.Models;

namespace CashOrCard.Repository
{
    public class BaseRepository<T> : IBaseRepository<T> where T : class,new()
    {
        private readonly DbContext _dbContext = CocContextFactory.GetCurrentDbContext();

        public bool AddEntities(T entity)
        {
            _dbContext.Entry<T>(entity).State = EntityState.Added;
            return _dbContext.SaveChanges() > 0;
        }

        public T AddEntity(T entity)
        {
            _dbContext.Entry<T>(entity).State = EntityState.Added;
            _dbContext.SaveChanges();
            return entity;
        }

        public bool UpdateEntities(T entity)
        {
            _dbContext.Set<T>().Attach(entity);
            _dbContext.Entry<T>(entity).State = EntityState.Modified;
            return _dbContext.SaveChanges() > 0;
        }

        public bool DeleteEntities(T entity)
        {
            _dbContext.Set<T>().Attach(entity);
            _dbContext.Entry<T>(entity).State = EntityState.Deleted;
            return _dbContext.SaveChanges() > 0;
        }

        public IQueryable<T> LoadEntities(Func<T, bool> wherelambda)
        {
            return _dbContext.Set<T>().Where<T>(wherelambda).AsQueryable();
        }

        public IQueryable<T> LoadPagerEntities<S>(int pageSize, int pageIndex, out int total,
            Func<T, bool> whereLambda, bool isAsc, Func<T, S> orderByLambda)
        {
            var tempData = _dbContext.Set<T>().Where<T>(whereLambda);

            total = tempData.Count();

            if (isAsc)
            {
                tempData = tempData.OrderBy<T, S>(orderByLambda).
                      Skip<T>(pageSize * (pageIndex - 1)).
                      Take<T>(pageSize).AsQueryable();
            }
            else
            {
                tempData = tempData.OrderByDescending<T, S>(orderByLambda).
                     Skip<T>(pageSize * (pageIndex - 1)).
                     Take<T>(pageSize).AsQueryable();
            }
            return tempData.AsQueryable();
        }

        public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
        {
            return _dbContext.Set<T>().Where(predicate);
        }

        public T Get(int id)
        {
            return _dbContext.Set<T>().Find(id);
        }

        public bool Save()
        {
            return _dbContext.SaveChanges() > 0;
        }

        public void Delete(T o)
        {
            _dbContext.Set<T>().Remove(o);
        }
    }
}